﻿// Veizu.Common
// DirectoryUtil.cs
// 日期:  2018-11-22 15:29
// 公司:           松山湖材料实验室
// 功能:
// 作者:           陈琦

using System;
using System.IO;
using System.Security.AccessControl;

namespace RoboSensors.Tools
{
    public sealed class DirectoryHelper
    {
        public static bool IsWriteable(string path)
        {
            if (!Directory.Exists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch
                {
                    return false;
                }
            }
            try
            {
                string path2 = ".test." + Guid.NewGuid().ToString().Substring(0, 5);
                string path3 = Path.Combine(path, path2);
                File.WriteAllLines(path3, new[]
                {
                "test"
                });
                File.Delete(path3);
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static bool IsDiskSpaceEnough(string path, ulong requiredSpace)
        {
            string pathRoot = Path.GetPathRoot(path);
            ulong freeSpace = GetFreeSpace(pathRoot);
            return requiredSpace <= freeSpace;
        }

        public static ulong GetFreeSpace(string driveName)
        {
            ulong result = 0uL;
            try
            {
                DriveInfo driveInfo = new DriveInfo(driveName);
                result = (ulong)driveInfo.AvailableFreeSpace;
            }
            catch
            {
                // ignored
            }
            return result;
        }

        public static ulong ConvertByteCountToKByteCount(ulong byteCount)
        {
            return byteCount / 1024uL;
        }

        public static float ConvertKByteCountToMByteCount(ulong kByteCount)
        {
            // ReSharper disable once PossibleLossOfFraction
            return kByteCount / 1024uL;
        }

        public static float ConvertMByteCountToGByteCount(float kByteCount)
        {
            return kByteCount / 1024f;
        }

        public static string[] GetFileNames(string directoryPath)
        {
            if (!IsExistDirectory(directoryPath))
            {
                throw new FileNotFoundException();
            }
            return Directory.GetFiles(directoryPath);
        }

        public static string[] GetFileNames(string directoryPath, string searchPattern, bool isSearchChild)
        {
            if (IsExistDirectory(directoryPath))
            {
                try
                {
                    if (!isSearchChild)
                    {
                        return Directory.GetFiles(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
                    }
                    return Directory.GetFiles(directoryPath, searchPattern, SearchOption.AllDirectories);
                }
                catch (IOException ex)
                {
                    throw ex;
                }
            }
            throw new FileNotFoundException();
        }

        public static string[] GetDirectories(string directoryPath)
        {
            try
            {
                return Directory.GetDirectories(directoryPath);
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static string[] GetDirectories(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                if (!isSearchChild)
                {
                    return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
                }
                return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.AllDirectories);
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static string CreateDirectoryByDate(string rootPath)
        {
            return CreateDirectoryByDate(rootPath, "yyyy-MM-dd");
        }

        public static string CreateDirectoryByDate(string rootPath, string formatString)
        {
            if (!IsExistDirectory(rootPath))
            {
                throw new DirectoryNotFoundException("the rootPath is not found");
            }
            bool flag;
            switch (formatString)
            {
                case "yyyy-MM-dd-HH":
                    flag = true;
                    break;
                case "yyyy-MM-dd":
                    flag = false;
                    break;
                default:
                    flag = false;
                    break;
            }
            DateTime now = DateTime.Now;
            int num = now.Year;
            string text = rootPath + "\\" + num.ToString();
            CreateDirectory(text);
            string str = text;
            now = DateTime.Now;
            num = now.Month;
            text = str + "\\" + num.ToString("00");
            CreateDirectory(text);
            string str2 = text;
            now = DateTime.Now;
            num = now.Day;
            text = str2 + "\\" + num.ToString("00");
            CreateDirectory(text);
            if (flag)
            {
                string str3 = text;
                now = DateTime.Now;
                num = now.Hour;
                text = str3 + "\\" + num.ToString("00");
                CreateDirectory(text);
            }
            return text;
        }

        public static void AssertDirExist(string filePath)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(filePath);
            if (!directoryInfo.Exists)
            {
                directoryInfo.Create();
            }
        }

        public static bool IsExistDirectory(string directoryPath)
        {
            return Directory.Exists(directoryPath);
        }

        public static bool IsEmptyDirectory(string directoryPath)
        {
            try
            {
                string[] fileNames = GetFileNames(directoryPath);
                if (fileNames.Length <= 0)
                {
                    string[] directories = GetDirectories(directoryPath);
                    if (directories.Length <= 0)
                    {
                        return true;
                    }
                    return false;
                }
                return false;
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static bool ContainFile(string directoryPath, string searchPattern)
        {
            try
            {
                string[] fileNames = GetFileNames(directoryPath, searchPattern, false);
                if (fileNames.Length != 0)
                {
                    return true;
                }
                return false;
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static bool ContainFile(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                string[] fileNames = GetFileNames(directoryPath, searchPattern, true);
                if (fileNames.Length != 0)
                {
                    return true;
                }
                return false;
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static void CreateDirectory(string directoryPath)
        {
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
        }

        public static void ClearDirectory(string directoryPath)
        {
            if (Directory.Exists(directoryPath))
            {
                string[] fileNames = GetFileNames(directoryPath);
                for (int i = 0; i < fileNames.Length; i++)
                {
                    FileHelper.DeleteFile(fileNames[i]);
                }
                string[] directories = GetDirectories(directoryPath);
                for (int i = 0; i < directories.Length; i++)
                {
                    DeleteDirectory(directories[i]);
                }
            }
        }

        public static void DeleteDirectory(string directoryPath)
        {
            if (Directory.Exists(directoryPath))
            {
                Directory.Delete(directoryPath, true);
            }
        }

        public static void DeleteDirectory(DirectoryInfo directoryInfo)
        {
            if (directoryInfo.Exists)
            {
                FileSystemInfo[] fileSystemInfos = directoryInfo.GetFileSystemInfos();
                foreach (FileSystemInfo fileSystemInfo in fileSystemInfos)
                {
                    if (fileSystemInfo is FileInfo)
                    {
                        FileInfo fileInfo = (FileInfo)fileSystemInfo;
                        fileInfo.Attributes = FileAttributes.Normal;
                        fileInfo.Delete();
                    }
                    else if (fileSystemInfo is DirectoryInfo)
                    {
                        DirectoryInfo directoryInfo2 = (DirectoryInfo)fileSystemInfo;
                        directoryInfo2.Attributes = FileAttributes.Normal;
                        DeleteDirectory(directoryInfo2);
                    }
                }
                directoryInfo.Attributes = FileAttributes.Normal;
                directoryInfo.Delete();
            }
        }

        public static string GetSystemDirectory()
        {
            return Environment.SystemDirectory;
        }

        public static string GetSpeicalFolder(Environment.SpecialFolder folderType)
        {
            return Environment.GetFolderPath(folderType);
        }

        public static string GetTempPath()
        {
            return Path.GetTempPath();
        }

        public static string GetCurrentDirectory()
        {
            return Directory.GetCurrentDirectory();
        }

        public static void SetCurrentDirectory(string path)
        {
            Directory.SetCurrentDirectory(path);
        }

        public static char[] GetInvalidPathChars()
        {
            return Path.GetInvalidPathChars();
        }

        public static DriveInfo[] GetAllDrives()
        {
            return DriveInfo.GetDrives();
        }

        public static bool SetAccess(string user, string folder)
        {
            FileSystemAccessRule rule = new FileSystemAccessRule(user, FileSystemRights.FullControl, InheritanceFlags.None, PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
            DirectoryInfo directoryInfo = new DirectoryInfo(folder);
            DirectorySecurity accessControl = directoryInfo.GetAccessControl(AccessControlSections.Access);
            bool modified;
            accessControl.ModifyAccessRule(AccessControlModification.Set, rule, out modified);
            if (modified)
            {
                rule = new FileSystemAccessRule(user, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow);
                accessControl.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
                if (modified)
                {
                    directoryInfo.SetAccessControl(accessControl);
                    return true;
                }
                return false;
            }
            return false;
        }

    }
}